from django.shortcuts import render
from QQLoginTool.QQtool import OAuthQQ
from django.views import View
from django.conf import settings
from django import http
from apps.oauth.models import OAuthQQUser
from django.contrib.auth import login
from apps.oauth.utils import generate_access_token_openid, check_access_token_openid
import json, re
from django_redis import get_redis_connection
from apps.users.models import User

# Create your views here.


class QQURLView(View):
    """QQ登录扫码链接"""
    def get(self, request):
        # 接收next参数,默认为:'/'
        next = request.GET.get('next', '/')

        # 创建OAuthQQ对象
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                        client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI,
                        state=next)

        # 调用提供QQ登录扫码链接的接口函数
        login_url = oauth.get_qq_url()

        # 响应结果
        return http.JsonResponse({'code': 0, 'errmsg': 'OK', 'login_url': login_url})


class QQUserView(View):
    """处理授权后的回调"""
    def get(self, request):
        # 获取code
        code = request.GET.get('code')
        if not code:
            return http.JsonResponse({'code': 400, 'errmsg': '缺少code'})

        # 创建SDK的对象
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                        client_secret=settings.QQ_CLIENT_SECRET,
                       redirect_uri=settings.QQ_REDIRECT_URI)

        try:
            # 使用code获取access_token
            access_token = oauth.get_access_token(code)
            # 使用access_token获取openid
            openid = oauth.get_open_id(access_token)
        except BaseException as e:
            return http.JsonResponse({'code': 400, 'errmsg': 'OAuth2.0认证失败'})

        # 使用openid判断当前QQ用户是否绑定美多用户
        try:
            oauth_model = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:
            # 未绑定,引导至绑定页面
            # openid交给用户保存,方便处理
            # 通过状态码300告诉前端作出相应处理
            access_token_openid = generate_access_token_openid(openid)
            return http.JsonResponse({'code': 300, 'errmsg': '用户未绑定', 'access_token': access_token_openid})
        else:
            # 已绑定,实现状态保持
            # 提示：在实现QQ登录时，真正登录到美多商城的不是QQ用户，而是QQ用户绑定的美多商城用户
            login(request=request, user=oauth_model.user)

            # 响应结果
            response = http.JsonResponse({'code': 0, 'errmsg': 'OK'})
            response.set_cookie('username', oauth_model.user.username, max_age=3600 * 24 * 14)
            return response

    def post(self, request):
        """实现openid绑定用户逻辑"""
        # 接收参数
        json_dict = json.loads(request.body.decode())
        mobile = json_dict.get('mobile')
        password = json_dict.get('password')
        sms_code_client = json_dict.get('sms_code')
        access_token = json_dict.get('access_token')

        # 校验参数
        if not all([mobile, password, sms_code_client, access_token]):
            return http.JsonResponse({'code': 400, 'errmsg': '缺少必传参数'})
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.JsonResponse({'code': 400, 'errmsg': '参数mobile有误'})
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return http.JsonResponse({'code': 400, 'errmsg': '参数password有误'})

        # 校验短信验证码
        redis_conn = get_redis_connection('verify_code')
        sms_code_server = redis_conn.get('sms_%s' % mobile)
        if not sms_code_server:
            return http.JsonResponse({'code': 400, 'errmsg': '短信验证码过期'})
        if sms_code_client != sms_code_server.decode():
            return http.JsonResponse({'code': 400, 'errmsg': '短信验证码错误'})

        # 校验openid
        openid = check_access_token_openid(access_token)
        if not openid:
            return http.JsonResponse({'code': 400, 'errmsg': '参数openid有误'})

        # 判断手机号对应用户是否存在
        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist:
            # 不存在,新建用户
            user = User.objects.create_user(username=mobile, password=password, mobile=mobile)
        else:
            # 存在,校验密码
            if not user.check_password(password):
                return http.JsonResponse({'code': 400, 'errmsg': '密码错误'})

        # 绑定openid至用户
        try:
            OAuthQQUser.objects.create(user=user, openid=openid)
        except BaseException as e:
            return http.JsonResponse({'code': 400, 'errmsg': 'QQ登录失败'})

        # 实现状态保持
        login(request=request, user=user)
        response = http.JsonResponse({'code': 0, 'errmsg': 'OK'})
        response.set_cookie('username', user.username, max_age=3600 * 24 * 14)

        # 响应结果
        return response


